(function($){
    $.fn.pagination = function(opt) {
        var page = opt["page"];
        var stepFun = opt["stepFun"];
        var $target = $(this);

        $target.empty();

        var onClick = function($link, index) {
            if($link.parent().is(".active")) {
                return;
            }

            var result = stepFun(index);
            if(typeof result == "function"){
                $link.on("click", result);
            }else if(typeof result == "string") {
                $link.attr("href", result);
            }
        };

        var $item = $("<li>").appendTo($target);
        var $link = $('<a aria-label="Previous"><span aria-hidden="true">«</span></a>').appendTo($item);
        onClick($link, page["first"]);

        $item = $("<li>").appendTo($target);
        $link = $('<a aria-label="Previous"><span aria-hidden="true">‹</span></a>').appendTo($item);
        onClick($link, page["prev"]);

        var pageNo = page["pageNo"];
        var first = page["first"];
        var last = page["last"];
        var seed = 3;
        var start = pageNo - seed;
        var end = pageNo + seed;

        if(start < first) {
            end -= (start - 1);
            start = first;
        }

        if(end > last) {
            start -= (end - last);
            end = last;
        }

        if(start < first) {
            start = first;
        }

        for(var i=start; i <= end; i++) {
            $item = $("<li>").appendTo($target);
            $link = $('<a>' + i + '</a>').appendTo($item);
            if(pageNo == i) {
                $item.addClass("active");
            }

            onClick($link, i);
        }

        $item = $("<li>").appendTo($target);
        $link = $('<a aria-label="Next"><span aria-hidden="true">›</span></a>').appendTo($item);
        onClick($link, page["next"]);

        $item = $("<li>").appendTo($target);
        $link = $('<a aria-label="Next"><span aria-hidden="true">»</span></a>').appendTo($item);
        onClick($link, page["last"]);
    }
})(jQuery);